package com.sf.grd.trade.micro.util;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sf.shiva.trtms.ground.core.utils.JSONUtils;

public class HttpRequestUtils {
	private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtils.class);
	private static final String CHARSET_UTF_8 = "UTF-8";

	private static final String HTTP = "http";
	private static final String HTTPS = "https";
	private static SSLConnectionSocketFactory sslsf = null;
	private static PoolingHttpClientConnectionManager cm = null;
	private static SSLContextBuilder builder = null;
	static {
		try {
			builder = new SSLContextBuilder();
			// 全部信任 不做身份鉴定
			builder.loadTrustMaterial(null, new TrustStrategy() {
				@Override
				public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
					return true;
				}
			});
			sslsf = new SSLConnectionSocketFactory(builder.build(),
					new String[] { "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
			Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
					.register(HTTP, new PlainConnectionSocketFactory()).register(HTTPS, sslsf).build();
			cm = new PoolingHttpClientConnectionManager(registry);
			cm.setMaxTotal(1000);// max connection
		} catch (Exception e) {
			logger.error("ssl init error", e);
		}
	}

	private HttpRequestUtils() {
	}

	public static String postWithStringParam(String url, Object toJson) {
		return postWithStringParam(url, JSONUtils.toJson(toJson));
	}

	public static String postWithStringParam(String url, String stringParam) {
		CloseableHttpClient httpClient = null;
		try {
			httpClient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(url);

			StringEntity entity = new StringEntity(stringParam, CHARSET_UTF_8);// 解决中文乱码问题
			entity.setContentEncoding(CHARSET_UTF_8);
			entity.setContentType("application/json");
			httpPost.setEntity(entity);

			return httpClient.execute(httpPost, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws IOException {
					int statusCode = response.getStatusLine().getStatusCode();
					if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
						return EntityUtils.toString(response.getEntity(), CHARSET_UTF_8);
					}
					return null;
				}
			});
		} catch (IOException e) {
			logger.error("HttpRequestUtils.postWithStringParam error,url:" + url + ",stringParam:" + stringParam, e);
			throw new RuntimeException(e);
		} finally {
			HttpClientUtils.closeQuietly(httpClient);
		}
	}
	
	/**
	 * 发送 SSL GET 请求（HTTPS）
	 * 
	 * @param url
	 * @return
	 */
	public static String getSSL(String url) {
		CloseableHttpClient httpClient = null;
		try {
			httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm)
					.setConnectionManagerShared(true).build();
			HttpGet httpGet = new HttpGet(url);

			return httpClient.execute(httpGet, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws IOException {
					int statusCode = response.getStatusLine().getStatusCode();
					if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
						return EntityUtils.toString(response.getEntity(), CHARSET_UTF_8);
					}
					return null;
				}
			});
		} catch (IOException e) {
			logger.error("HttpRequestUtils.getSSL error,url:" + url, e);
			throw new RuntimeException(e);
		} finally {
			HttpClientUtils.closeQuietly(httpClient);
		}
	}
	
	/**
	 * 发送 SSL POST 请求（HTTPS）
	 * 
	 * @param url
	 * @param toJson
	 * @return
	 */
	public static String postSSLWithJsonParam(String url, Object toJson) {
		return postSSL(url, JSONUtils.toJson(toJson));
	}
	
	/**
	 * 发送 SSL POST 请求（HTTPS）
	 * 
	 * @param url
	 * @param stringParam
	 * @return
	 */
	public static String postSSL(String url,String stringParam) {
		CloseableHttpClient httpClient = null;
		try {
			httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm)
					.setConnectionManagerShared(true).build();
			HttpPost httpPost = new HttpPost(url);

			StringEntity entity = new StringEntity(stringParam, CHARSET_UTF_8);// 解决中文乱码问题
			entity.setContentEncoding(CHARSET_UTF_8);
			entity.setContentType("application/json");
			httpPost.setEntity(entity);

			return httpClient.execute(httpPost, new ResponseHandler<String>() {
				@Override
				public String handleResponse(HttpResponse response) throws IOException {
					int statusCode = response.getStatusLine().getStatusCode();
					if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_INTERNAL_SERVER_ERROR) {
						return EntityUtils.toString(response.getEntity(), CHARSET_UTF_8);
					}
					return null;
				}
			});
		} catch (IOException e) {
			logger.error("HttpRequestUtils.postSSL error,url:" + url, e);
			throw new RuntimeException(e);
		} finally {
			HttpClientUtils.closeQuietly(httpClient);
		}
	}
}
